package com.yh.csx.bsf.ods;

import com.alibaba.otter.canal.protocol.Message;
import com.yh.csx.bsf.core.base.BsfException;
import com.yh.csx.bsf.core.util.FileUtils;
import com.yh.csx.bsf.core.util.LogUtils;
import lombok.var;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public abstract class AbstractCanalServerProvider {
    protected StragtegyProvider stragtegyProvider=new StragtegyProvider();

    public void start(){

        //启动项目
        if(ProcessUtils.isWinOs())
        {
            var file = new File("canal/bin/startup.bat");
            ProcessUtils.cmd("cd "+file.getParentFile().getAbsolutePath()+"&"+"startup.bat",false);
            //ProcessUtils.cmd(file.getAbsolutePath());
        }
        else {
            var file = new File("canal/bin/startup.sh");
            var cmd="cd "+file.getParentFile().getAbsolutePath()+";sh "+"startup.sh";
            LogUtils.info(this.getClass(),"ods","启动canal server脚本:"+cmd);
            ProcessUtils.cmd(cmd,true);
        }
        LogUtils.info(this.getClass(),"ods","canal server 已启动!");
    }

    public void stop(){
    	
        //检查杀死进程
        if(ProcessUtils.isWinOs())
        {
            if(killWinCanalServer()){
                LogUtils.info(this.getClass(), "ods", "canal server 已关闭!");
            }
        }
        else {
        	
            var file = new File("canal/bin/stop.sh");
            if(file.exists()) {
                ProcessUtils.cmd("cd" + file.getParentFile().getAbsolutePath() + ";sh stop.sh", true);
            }
            ProcessUtils.cmd("ps -ef | grep CanalLauncher | grep -v grep | awk '{print $2}' | xargs kill -9",true);
            var canalid = new File("canal/bin/canal.pid");
            if(canalid.exists()) {
            	canalid.delete();
            }
            LogUtils.info(this.getClass(), "ods", "canal server 已关闭!");
        }

    }

    protected void unzip(boolean isDeleteOld){
    	 var canal = new File("canal");
         if (canal.exists()) {
        	 if(isDeleteOld) {
        		 FileUtils.deleteDir(canal.getAbsoluteFile());
        	 }else {
        		 return ;
        	 }
         }
        var stream =  this.getClass().getResourceAsStream("/canal.tar.gz");
        var file = new File("canal.tar.gz");
        if(file.exists())
        {
            file.delete();
        }      
        LogUtils.info(this.getClass(),"ods","释放canalserver:"+file.getAbsolutePath());
        FileUtils.saveStream(stream, file.getAbsolutePath());
        LogUtils.info(this.getClass(),"ods","解压至:"+new File("canal").getAbsolutePath());
        uncompress(file.getAbsolutePath(),new File("canal").getAbsolutePath());
        var example = new File("canal/conf/example");
        example.renameTo(new File("canal/example").getAbsoluteFile());
        FileUtils.deleteDir(example.getAbsoluteFile());
        file.delete();
    }

    protected void uncompress(String sourcePath, String extractPath){
        File sourceFile = new File(sourcePath);
        // decompressing *.tar.gz files to tar
        try(var fs = new FileInputStream(sourceFile)){
            try(var gzip = new GzipCompressorInputStream(fs))
            {
                try(TarArchiveInputStream fin = new TarArchiveInputStream(gzip)) {
                    File extraceFolder = new File(extractPath);
                    TarArchiveEntry entry;
                    // 将 tar 文件解压到 extractPath 目录下
                    while ((entry = fin.getNextTarEntry()) != null) {
                        if (entry.isDirectory()) {
                            continue;
                        }
                        File curfile = new File(extraceFolder, entry.getName());
                        File parent = curfile.getParentFile();
                        if (!parent.exists()) {
                            parent.mkdirs();
                        }
                        // 将文件写出到解压的目录
                        try(var out = new FileOutputStream(curfile))
                        {
                            IOUtils.copy(fin, out);
                        }

                    }
                }
            }
        }
        catch (Exception exp){
            throw new BsfException(exp);
        }
    }

    protected boolean killWinCanalServer(){
        var rs= ProcessUtils.cmd("jps -l",true);
        for(var result :rs){
            if(result.contains("CanalLauncher"))
            {
                var pid = result.split(" ")[0].trim().replace("\r","");
                ProcessUtils.cmd("taskkill /pid "+pid+" /F",true);
                return true;
            }
        }
        return false;
    }

}
